package com.tiancheng.trade.payment.controller.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.nacos.shaded.com.google.gson.JsonObject;
import com.lkl.laop.sdk.LKLSDK;
import com.tiancheng.trade.commom.core.exception.BusinessException;
import com.tiancheng.trade.commom.core.exception.error.BusinessErrorInfoEnum;
import com.tiancheng.trade.commom.core.utils.JsonUtil;
import com.tiancheng.trade.payment.channel.apple.AppleUtils;
import com.tiancheng.trade.payment.channel.ums.utils.UmsQrcUtil;
import com.tiancheng.trade.payment.channel.umsdhjt.request.UmsDhjtSettleNotifyRequest;
import com.tiancheng.trade.payment.configuration.PaypalConfig;
import com.tiancheng.trade.commom.core.enums.PaymentChannelEnum;
import com.tiancheng.trade.payment.enums.PaypalStateEnum;
import com.tiancheng.trade.payment.service.NotifyService;
import com.tiancheng.trade.payment.util.CommonUtil;
import com.tiancheng.trade.payment.util.JacksonJsonUtil;
import com.tiancheng.trade.payment.util.RequestToMapUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @Auther: ld
 * @Date: 2024/3/3 10:21
 * @Param ${tags}
 * @Description: 支付成功回调通知
 */
@RestController
@RequestMapping("/notify")
@Slf4j
public class PaymentNotifyController {
    @Resource
    private JacksonJsonUtil jacksonJsonUtil;
    @Resource
    private NotifyService notifyService;
    @Autowired
    private PaypalConfig paypalConfig;

    /**
     * 招总行计平支付结果回调
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/result/cmb/pay")
    public String cmbPayResult(@RequestBody String params) {
        log.info("招总行计平支付结果回调数据:{}", params);
        int resStatus = 0;
        try {
            Map<String, Object> paramsMap = CommonUtil.parseParams(params);
            notifyService.payNotifyHandle(paramsMap, PaymentChannelEnum.CMB);
        } catch (BusinessException e) {
            log.error("招总行计平支付回调处理失败: {}", e.getMessage());
            if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_NO_FLOW.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.MESSAGE_SEND_ERROR.getCode() == e.getErrorInfo().getCode()) {
                resStatus = -1;
            } else {
                resStatus = -1;
            }
        } catch (Exception e) {
            log.error("招总行计平支付回调处理失败: {}", e.getMessage());
            resStatus = -1;
        }
        JsonObject result = new JsonObject();
        result.addProperty("ret", resStatus);
        result.addProperty("msg", resStatus == 0 ? "ok" : "fail");
        return result.toString();
    }

    /**
     * 招总行计平退款结果回调
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/result/cmb/refund")
    public String cmbRefundResult(@RequestBody String params) {
        int resStatus = 0;
        try {
            // todo 这个判断是因为之前php系统转发时，做了一次decode，现在计平直接回调交易中台，所以要自己做一次decode
            if (params.contains("UserProvideMsg%253D")) {
                params = URLDecoder.decode(params, "utf-8");
            }
            log.info("招总行计平退款结果回调数据:{}", params);
            Map<String, Object> paramsMap = CommonUtil.parseParams(params);
            notifyService.refundNotifyHandle(paramsMap, PaymentChannelEnum.CMB);
        } catch (BusinessException e) {
            log.error("招总行计平退款回调处理失败: {}", e.getMessage(), e);
            if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_REFUND_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_REFUND_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_REFUND_NO_FLOW.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_REFUND_TIMEOUT_FLOW_ERROR.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.MESSAGE_SEND_ERROR.getCode() == e.getErrorInfo().getCode()) {
                resStatus = -1;
            } else {
                resStatus = -1;
            }
            log.error("招总行计平退款回调处理失败 错误码: {} resStatus:{}", e.getErrorInfo().getCode(), resStatus);
        } catch (Exception e) {
            log.error("招总行计平退款回调处理失败: {}", e.getMessage(), e);
            resStatus = -1;
        }
        JsonObject result = new JsonObject();
        result.addProperty("ret", resStatus);
        result.addProperty("msg", resStatus == 0 ? "ok" : "fail");
        return result.toString();
    }

    /**
     * 富滇银行支付结果通知
     *
     * @param payResult
     * @return
     */
    @PostMapping(value = "/result/fudian/pay")
    public String fudianPayResult(@RequestBody String payResult) {
        log.info("富滇支付回调数据: {}", payResult);
        int resStatus = 0;
        try {
            Map<String, Object> paramsMap = jacksonJsonUtil.fromJson(payResult, Map.class);
            notifyService.payNotifyHandle(paramsMap, PaymentChannelEnum.FUDIAN);
        } catch (BusinessException e) {
            log.error("富滇支付回调处理失败: {}", e.getMessage());
            if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_NO_FLOW.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.MESSAGE_SEND_ERROR.getCode() == e.getErrorInfo().getCode()) {
                resStatus = -1;
            } else {
                resStatus = 1;
            }
        } catch (Exception e) {
            log.error("富滇支付回调处理失败: {}", e.getMessage());
            resStatus = 1;
        }
        JsonObject res = new JsonObject();
        res.addProperty("status", resStatus);
        res.addProperty("msg", resStatus == 0 ? "通知成功" : "通知失败");
        return res.toString();
    }


    /**
     * 银联渠道支付结果回调
     *
     * @param paramsMap
     * @return
     */
    @RequestMapping(value = "/result/ums/pay")
    public String umsPayResult(@RequestParam Map<String, Object> paramsMap) {
        try {
            log.info("银联渠道回调数据:{}", JSON.toJSONString(paramsMap));
        } catch (Exception e) {
            log.error("银联渠道回调数据json error");
        }
        int resStatus = 0;
        resStatus = umsCallbackHandle(paramsMap, resStatus, PaymentChannelEnum.UMS);
        return resStatus == 0 ? "SUCCESS" : "FAILED";
    }

    /**
     * 银联渠道支付结果回调
     *
     * @param paramsMap
     * @return
     */
    @RequestMapping(value = "/result/umsMop/pay")
    public String umsMopPayResult(@RequestParam Map<String, Object> paramsMap) {
        try {
            log.info("银联天满渠道回调数据:{}", JSON.toJSONString(paramsMap));
        } catch (Exception e) {
            log.error("银联天满渠道回调数据json error");
        }
        int resStatus = 0;
        resStatus = umsCallbackHandle(paramsMap, resStatus, PaymentChannelEnum.UMS_MOP);
        return resStatus == 0 ? "SUCCESS" : "FAILED";
    }

    /**
     * 银联渠道支付结果回调
     *
     * @param paramsMap
     * @return
     */
    @RequestMapping(value = "/result/umsDhjt/pay")
    public String umsDhjtPayResult(@RequestParam Map<String, Object> paramsMap) {
        try {
            log.info("银联-大华接通渠道回调数据:{}", JSON.toJSONString(paramsMap));
        } catch (Exception e) {
            log.error("银联天满渠道回调数据json error");
        }
        int resStatus = 0;
        resStatus = umsCallbackHandle(paramsMap, resStatus, PaymentChannelEnum.UMS_DHJT);
        return resStatus == 0 ? "SUCCESS" : "FAILED";
    }

    /**
     * 银联渠道支付结果回调-json
     * 用于偶发消息推送异常时，手动接口处理
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/result/ums/payJson")
    public String umsPayResult(@RequestBody String params) {
        log.info("银联-大华接通渠道回调数据:{}", params);
        Map<String, Object> paramsMap = JSON.parseObject(params, new TypeReference<Map<String, Object>>() {
        });
        int resStatus = 0;
        resStatus = umsCallbackHandle(paramsMap, resStatus, PaymentChannelEnum.UMS);
        return resStatus == 0 ? "SUCCESS" : "FAILED";
    }

    /**
     * 银联渠道-新购物车-支付结果回调
     *
     * @param paramsMap
     * @return
     */
    @RequestMapping(value = "/result/umsShop/pay")
    public String umsShopPayResult(@RequestParam Map<String, Object> paramsMap) {
        try {
            log.info("银联-新购物车渠道回调数据:{}", JSON.toJSONString(paramsMap));
        } catch (Exception e) {
            log.error("银联-新购物车回调数据json error");
        }
        int resStatus = 0;
        resStatus = umsCallbackHandle(paramsMap, resStatus, PaymentChannelEnum.UMS_SHOP);
        return resStatus == 0 ? "SUCCESS" : "FAILED";
    }

    private int umsCallbackHandle(Map<String, Object> paramsMap, int resStatus, PaymentChannelEnum channelEnum) {
        try {
            if (channelEnum == PaymentChannelEnum.UMS) {
                if (paramsMap.containsKey("refundAmount") && paramsMap.get("refundAmount") != null &&
//                    paramsMap.containsKey("refundOrderId") && paramsMap.get("refundOrderId")!=null &&
                        ((paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_REFUND")) || (paramsMap.get("billStatus") != null && paramsMap.get("billStatus").toString().equals("REFUND")))) {
                    // 退款成功处理
                    log.info("银联渠道退款结果回调数据:{}", paramsMap);
                    notifyService.refundNotifyHandle(paramsMap, channelEnum);
                } else if (paramsMap.containsKey("seqId") && paramsMap.get("seqId") != null &&
                        ((paramsMap.containsKey("targetOrderId") && paramsMap.get("targetOrderId") != null)
                                || (paramsMap.containsKey("billStatus") && paramsMap.get("billStatus") != null && paramsMap.get("billStatus").toString().equals("PAID")))) {
                    log.info("银联渠道支付结果回调数据:{}", paramsMap);
                    // 支付回调处理
                    notifyService.payNotifyHandle(paramsMap, channelEnum);
                } else {
                    log.info("银联渠道其他结果回调数据:{}", paramsMap);
                }
                // 银联数据暂不推送支付流水到对账中心
            } else if (channelEnum == PaymentChannelEnum.UMS_DHJT) {
                if (paramsMap.containsKey("refundAmount") && paramsMap.get("refundAmount") != null &&
//                    paramsMap.containsKey("refundOrderId") && paramsMap.get("refundOrderId")!=null &&
                        ((paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_REFUND")) || (paramsMap.get("billStatus") != null && paramsMap.get("billStatus").toString().equals("REFUND")))) {
                    // 退款成功处理
                    log.info("银联大华捷通渠道退款结果回调数据:{}", paramsMap);
                    notifyService.refundNotifyHandle(paramsMap, channelEnum);
                } else if (paramsMap.containsKey("seqId") && paramsMap.get("seqId") != null &&
                        ((paramsMap.containsKey("targetOrderId") && paramsMap.get("targetOrderId") != null)
                                || (paramsMap.containsKey("status") && paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_SUCCESS")))) {
                    log.info("银联渠道支付结果回调数据:{}", paramsMap);
                    // 支付回调处理
                    notifyService.payNotifyHandle(paramsMap, channelEnum);
                } else {
                    log.info("银联渠道其他结果回调数据:{}", paramsMap);
                }
            } else if (channelEnum == PaymentChannelEnum.UMS_MOP) {
                if (paramsMap.containsKey("refundAmount") && paramsMap.get("refundAmount") != null &&
//                    paramsMap.containsKey("refundOrderId") && paramsMap.get("refundOrderId")!=null &&
                        ((paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_REFUND")) || (paramsMap.get("billStatus") != null && paramsMap.get("billStatus").toString().equals("REFUND")))) {
                    // 退款成功处理
                    log.info("银联大华捷通渠道退款结果回调数据:{}", paramsMap);
                    notifyService.refundNotifyHandle(paramsMap, channelEnum);
                } else if (paramsMap.containsKey("seqId") && paramsMap.get("seqId") != null &&
                        ((paramsMap.containsKey("targetOrderId") && paramsMap.get("targetOrderId") != null)
                                || (paramsMap.containsKey("status") && paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_SUCCESS"))
                                || (paramsMap.containsKey("billStatus") && paramsMap.get("billStatus") != null && paramsMap.get("billStatus").toString().equals("PAID")))) {
                    log.info("银联渠道支付结果回调数据:{}", paramsMap);
                    // 支付回调处理
                    notifyService.payNotifyHandle(paramsMap, channelEnum);
                } else {
                    log.info("银联渠道其他结果回调数据:{}", paramsMap);
                }
            } else if (channelEnum == PaymentChannelEnum.UMS_SHOP) {
                if (paramsMap.containsKey("refundAmount") && paramsMap.get("refundAmount") != null &&
//                    paramsMap.containsKey("refundOrderId") && paramsMap.get("refundOrderId")!=null &&
                        ((paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_REFUND")) || (paramsMap.get("billStatus") != null && paramsMap.get("billStatus").toString().equals("REFUND")))) {
                    // 退款成功处理
                    log.info("银联新购物车渠道退款结果回调数据:{}", paramsMap);
                    notifyService.refundNotifyHandle(paramsMap, channelEnum);
                } else if (paramsMap.containsKey("seqId") && paramsMap.get("seqId") != null &&
                        ((paramsMap.containsKey("targetOrderId") && paramsMap.get("targetOrderId") != null)
                                || (paramsMap.containsKey("status") && paramsMap.get("status") != null && paramsMap.get("status").toString().equals("TRADE_SUCCESS")))) {
                    log.info("银联新购物车渠道支付结果回调数据:{}", paramsMap);
                    // 支付回调处理
                    notifyService.payNotifyHandle(paramsMap, channelEnum);
                } else {
                    log.info("银联新购物车其他结果回调数据:{}", paramsMap);
                }
            }

        } catch (BusinessException e) {
            log.error("银联渠道支付结果回调处理失败: {}", e.getMessage());
            if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_NO_FLOW.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_UNKNOWN_STATUS.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_REFUND_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_REFUND_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_REFUND_NO_FLOW.getCode() == e.getErrorInfo().getCode()) {
                resStatus = -1;
            } else if (BusinessErrorInfoEnum.CHANNEL_REFUND_TIMEOUT_FLOW_ERROR.getCode() == e.getErrorInfo().getCode()) {
                resStatus = 0;
            } else if (BusinessErrorInfoEnum.MESSAGE_SEND_ERROR.getCode() == e.getErrorInfo().getCode() ||
                    BusinessErrorInfoEnum.UMS_CHANNEL_SIGN_FAIL.getCode() == e.getErrorInfo().getCode()) {
                // 推送消息异常或者签名异常时，让渠道再次推送消息
                resStatus = -1;
            } else {
                resStatus = 1;
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("银联渠道回调消息处理失败: {}", e.getMessage());
            resStatus = -1;
        }
        return resStatus;
    }

    /**
     * 银联被扫支付回调：<br/>
     * 根据reqType类型不同区分
     *
     * @param req
     * @return
     */
    @RequestMapping(value = "/ums/qrcNotify")
    public void qrC2BNotify(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        // 获取银联通知服务器发送的后台通知参数
        Map<String, String> params = UmsQrcUtil.getAllRequestParam(req);
        log.info("银联被扫支付回调:{}", JSON.toJSONString(params));
        resp.setContentType("application/x-www-form-urlencoded; charset=utf-8");
        final Map<String, String> result = notifyService.qrC2BNotifyHandle(params);
        log.info("银联被扫支付回调: 响应银联:{}", result);
        resp.getWriter().write(UmsQrcUtil.getRequestParamString(result));
        //return
    }

    /**
     * 银联被扫支付回调：<br/>
     * 根据reqType类型不同区分
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/ums/qrcNotifyJson")
    public Map<String, String> qrcNotifyJson(@RequestBody String params) {
        Map<String, String> paramsMap = JSON.parseObject(params, new TypeReference<Map<String, String>>() {
        });
        // 获取银联通知服务器发送的后台通知参数
        log.info("银联被扫支付回调,json:{}", JSON.toJSONString(params));
        return notifyService.qrC2BNotifyHandle(paramsMap);
    }

    /**
     * paypal支付：ipn异步回调
     * paypal支付结果和退款结果回调处理，回调用的一个url
     * payment_status字段值：
     * Completed: 支付成功
     * Refunded: 退款成功
     */
    @RequestMapping(method = RequestMethod.POST, value = "/paypal/ipn/back")
    public void paypalCallback(HttpServletRequest request) {
        try {
            /**
             * 获取paypal请求参数,并拼接验证参数
             */
            Enumeration<String> en = request.getParameterNames();
            String str = PaypalConfig.VERIFY_PRE;
            while (en.hasMoreElements()) {
                String paramName = en.nextElement();
                String paramValue = request.getParameter(paramName);
                log.info("ipn回调入参解码-----" + paramName + ":" + URLDecoder.decode(paramValue, PaypalConfig.CHARSET));
                //此处的编码一定要和自己的网站编码一致，不然会出现乱码，paypal回复的通知为‘INVALID’
                str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue, PaypalConfig.CHARSET);
            }
            log.info("=========================================================================================");
            log.info("回传验证的信息为:" + str);

            /**
             * 将信息 POST 回给 PayPal 进行验证
             */
            String res = "";
            try {
                log.info("paypal当前使用的验证地址:" + paypalConfig.getWebscr());
                URL u = new URL(paypalConfig.getWebscr());
                HttpURLConnection uc = (HttpURLConnection) u.openConnection();
                uc.setRequestMethod("POST");
                uc.setDoOutput(true);
                uc.setDoInput(true);
                uc.setUseCaches(false);
                //设置 HTTP 的头信息
                uc.setRequestProperty("Content-Type", PaypalConfig.CONTENT_TYPE);
                PrintWriter pw = new PrintWriter(uc.getOutputStream());
                pw.println(str);
                pw.close();

                /**
                 * 接受 PayPal 对 IPN 回发的回复信息
                 */
                BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
                res = in.readLine();
                in.close();

                if (res == null || res == "") {
                    res = "0";
                }
            } catch (Exception e) {
                log.error("验证IPN通知异常 ：" + e.getMessage());
            }
            log.info("paypal回调验证res = " + res);

            /**
             * 将 POST 信息分配给本地变量，可以根据您的需要添加
             */
            // 交易状态 Completed 代表交易成功(支付成功)
            String paymentStatus = request.getParameter("payment_status");
            // 交易id
            String txnId = request.getParameter("txn_id");
            // 父交易id
            String parentTxnId = request.getParameter("parent_txn_id");
            log.info("paymentStatus = {},txnId={},parentTxnId={}", paymentStatus, txnId, parentTxnId);

            /**
             * 获取 PayPal 对回发信息的回复信息，判断刚才的通知是否为 PayPal 发出的
             */
            if (PaypalStateEnum.VERIFIED.getCode().equalsIgnoreCase(res)) {
                /*如果parent_txn_id为空时则表示是paypal的第一次通知,即支付结果通知；
                 parent_txn_id不为空的时候表示这是我们第二次或者多次接受到paypal通知,用于判断是否退款回调
                */
                Map requestMap = RequestToMapUtil.getParameterMap(request);
                if (StringUtil.isNotEmpty(parentTxnId)) {
                    //第二次或多次回调
                    if (paymentStatus.equals(PaypalStateEnum.IPN_REFUNDED.getCode())) {//退款回调
                        notifyService.refundNotifyHandle(requestMap, PaymentChannelEnum.PAYPAL);
                    }
                } else {
                    //第一次回调，支付结果回调
                    notifyService.payNotifyHandle(requestMap, PaymentChannelEnum.PAYPAL);
                }
            } else if (PaypalStateEnum.INVALID.getCode().equalsIgnoreCase(res)) {
                //非法信息，可以将此记录到您的日志文件中以备调查
                log.error("paypal发送IPN通知返回状态非法，请求参数：" + str);
            } else {
                //处理其他错误
                log.error("paypal发送IPN通知发生其他异常，请求参数：" + str);
            }
        } catch (Exception e) {
            log.error("接受IPN通知消息异常 ：" + e.getMessage());
        }

    }

    /**
     * apple消息通知
     *
     * @param signedPayload
     * @return
     */
    @RequestMapping(value = "/result/apple")
    public String appleNotify(@RequestBody String signedPayload, HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            if (!StringUtils.isEmpty(signedPayload)) {
                log.info("apple消息通知:{}", JSON.toJSONString(signedPayload));
                final Map<String, Object> msg = AppleUtils.appleMsgHandler(signedPayload);
                notifyService.refundNotifyHandle(msg, PaymentChannelEnum.APPLE);
            }
        } catch (Exception e) {
            log.error("苹果消息回调处理异常", e);
            response.setStatus(500);
            response.getWriter().write("msg handle error");
        }
        return "SUCCESS";
    }

    /**
     * 大华接通结算通知消息
     *
     * @param params
     * @return
     */
    @RequestMapping(value = "/result/dhjt/settleResult")
    public String dhjtSettleResult(@RequestBody UmsDhjtSettleNotifyRequest params) throws IOException {
        try {
            log.info("大华接通结算通知消息:{}", JSON.toJSONString(params));
            notifyService.dhjtSettleResult(params);
            return "SUCCESS";
        } catch (Exception e) {
            log.error("大华接通结算通知消息回调处理异常", e);
            return "ERROR";
        }
    }


    /**
     * 高诚支付通道-支付消息回调
     *
     * @param paramsMap
     * @return
     */
    @RequestMapping(value = "/gaoCheng/pay/notify")
    @ResponseBody
    public Map<String, Object> gaoChenPayResult(@RequestParam Map<String, Object> paramsMap) throws IOException {
        Map<String, Object> result = new HashMap<>();
        result.put("code", 200);
        result.put("message", "处理成功！");
        try {
            log.info("高诚支付通知消息:{}", JSON.toJSONString(paramsMap));
            notifyService.payNotifyHandle(paramsMap, PaymentChannelEnum.gao_cheng_nong_hang);

        } catch (BusinessException e) {
            if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {

            } else {
                result.put("code", 500);
                result.put("message", "处理失败！");
            }
        } catch (Exception e) {
            log.error("高诚支付通知消息回调处理异常", e);
            result.put("code", 500);
            result.put("message", "处理失败！");
        }
        return result;
    }

    /**
     * 拉卡拉支付通道-支付消息回调
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "/lklPay/pay/notify")
    @ResponseBody
    public Map<String, Object> lklPayResult(HttpServletRequest request) throws IOException {
        Map<String, Object> result = new HashMap<>();
        result.put("code", "SUCCESS");
        result.put("message", "处理成功！");
        try {
            String body = getBody(request);
            log.info("拉卡拉支付通知消息:{}", JSON.toJSONString(body));
            LKLSDK.notificationHandle(body, getAuthorization(request));
            notifyService.payNotifyHandle(JsonUtil.fromJson(body, Map.class), PaymentChannelEnum.lkl_pay);
        } catch (BusinessException e) {
            if (BusinessErrorInfoEnum.CHANNEL_CALLBACK_PAY_SUCCESS_DUP.getCode() == e.getErrorInfo().getCode()) {

            } else {
                result.put("code", "FAIL");
                result.put("message", "处理失败！");
            }
        } catch (Exception e) {
            log.error("拉卡拉支付通知消息回调处理异常", e);
            result.put("code", "FAIL");
            result.put("message", "处理失败！");
        }
        return result;
    }


    /**
     * 读取请求头
     */
    private String getAuthorization(HttpServletRequest request) {
        return request.getHeader("Authorization");
    }

    /**
     * 读取请求体
     */
    private String getBody(HttpServletRequest request) {
        try (InputStreamReader in = new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8)) {
            StringBuilder bf = new StringBuilder();
            int len;
            char[] chs = new char[1024];
            while ((len = in.read(chs)) != -1) {
                bf.append(new String(chs, 0, len));
            }
            return bf.toString();
        } catch (Exception e) {
            throw new RuntimeException("读取body失败");
        }

    }


}
